package hservice

import (
	"encoding/json"
	"strconv"
	"time"

	"advertoper/db"
	"advertoper/errorcode"

	"doubimeizhi.com/datatable"
	"doubimeizhi.com/utility"

	log "github.com/cihub/seelog"
)

var (
	defaultAdminManageService *AdminManageService
)

type AdminManageService struct {
}

func NewAdminManageService() *AdminManageService {
	service := &AdminManageService{}
	return service
}

func GetAdminManageService() *AdminManageService {
	if defaultAdminManageService == nil {
		defaultAdminManageService = NewAdminManageService()
	}
	return defaultAdminManageService
}

//添加总体容器布局
type TotalLayoutAddReq struct {
	Source              int   `json:"source"`                //页面位置,0:首页,1:维修频道,2:清洗,3:安装
	ContainerOrder      []int `json:"container_order"`       //整体容器的顺序,字段为容器id
	AndroidStartVersion int   `json:"android_start_version"` //android有效开始版本
	AndroidEndVersion   int   `json:"android_end_version"`   //android有效结束版本
	IosStartVersion     int   `json:"ios_start_version"`     //ios有效开始版本
	IosEndVersion       int   `json:"ios_end_version"`       //ios有效结束版本
}

//修改总体容器布局
type TotalLayoutUpdateReq struct {
	Id int `json:"id"`
	TotalLayoutAddReq
}

//查询总体容器布局
type TotalLayoutListReq struct {
	TotalLayoutUpdateReq
	InsertTime string `json:"insert_time"`
	UpdateTime string `json:"update_time"`
}

//添加容器
type ContainerAddReq struct {
	Source        int                    `json:"source"`         //页面位置,0:首页,1:维修频道,2:清洗,3:安装
	ContainerType int                    `json:"container_type"` //'容器类型,1:ZJBanner,2:ZJNews,3:ZJMultiView,4:ZJSingleView,5:ZJGoodsList,6:ZJTopic,7:ZJSeckill,8:zjpicture
	ContainerName string                 `json:"container_name"` //容器的名称(大标题)
	MoreRouters   string                 `json:"more_routers"`   //点击更多时的路由
	Layout        map[string]interface{} `json:"layout"`         //容器的整体样式布局,整体为json串
	ItemOrder     []int                  `json:"item_order"`     //该容器内部元素的排序，字段为元素id
}

//修改容器
type ContainerUpdateReq struct {
	ContainerId int `json:"container_id"`
	ContainerAddReq
}

//查询容器列表
type ContainerListReq struct {
	ContainerUpdateReq
	InsertTime string `json:"insert_time"`
	UpdateTime string `json:"update_time"`
}

//添加总体容器布局控制
func (p *AdminManageService) TotalLayoutAdd(req *TotalLayoutAddReq) (uint, string) {
	if req.AndroidStartVersion > req.AndroidEndVersion {
		return 101, "android开始版本不能大于结束版本"
	}
	if req.IosStartVersion > req.IosEndVersion {
		return 102, "ios开始版本不能大于结束版本"
	}
	//先获取android和ios的最大结束版本，与当前的开始版本对比
	sql := `select max(android_end_version) andendv ,max(ios_end_version) iosendv from total_layout where source=?`
	request, err := db.GetHomePageInfoMysqlHelper().Query(sql, req.Source)
	if err != nil {
		log.Errorf("query max end_version fail ,~~~TotalLayoutAdd,err is %s", err.Error())
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	}
	//判断android的开始版本是否合格
	if request[0]["andendv"] != nil {
		andendv, _ := strconv.Atoi(string(request[0]["andendv"].(int64)))
		if req.AndroidStartVersion <= andendv {
			return 103, "android开始版本与其他布局结束版本冲突"
		}
	}
	//判断ios的开始版本是否合格
	if request[0]["iosendv"] != nil {
		iosendv, _ := strconv.Atoi(string(request[0]["iosendv"].(int64)))
		if req.IosStartVersion <= iosendv {
			return 104, "ios开始版本与其他布局结束版本冲突"
		}
	}
	//插入
	nowTick := time.Now().Unix()
	b, _ := json.Marshal(req.ContainerOrder)
	data := make(map[string]*utility.MySQLFieldValue)
	data["source"] = utility.NewMySQLFieldValue(req.Source, false)
	data["container_order"] = utility.NewMySQLFieldValue(string(b), false)
	data["android_start_version"] = utility.NewMySQLFieldValue(req.AndroidStartVersion, false)
	data["android_end_version"] = utility.NewMySQLFieldValue(req.AndroidEndVersion, false)
	data["ios_start_version"] = utility.NewMySQLFieldValue(req.IosStartVersion, false)
	data["ios_end_version"] = utility.NewMySQLFieldValue(req.IosEndVersion, false)
	data["insert_tick"] = utility.NewMySQLFieldValue(nowTick, false)
	data["update_tick"] = utility.NewMySQLFieldValue(nowTick, false)
	mysqlHelper := db.GetHomePageInfoMysqlHelper()
	_, err2 := mysqlHelper.SaveRecord(data, "total_layout")
	if err2 != nil {
		log.Errorf("insert total_layout fail ,~~~TotalLayoutAdd,err is %s", err2.Error())
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	}
	return errorcode.EC_GL_SUCCESS, errorcode.Msg(errorcode.EC_GL_SUCCESS)
}

//修改总体容器布局控制
func (p *AdminManageService) TotalLayoutUpdate(req *TotalLayoutUpdateReq) (uint, string) {
	if req.AndroidStartVersion > req.AndroidEndVersion {
		return 101, "android开始版本不能大于结束版本"
	}
	if req.IosStartVersion > req.IosEndVersion {
		return 102, "ios开始版本不能大于结束版本"
	}

	//修改
	updaq := datatable.NewDataTableUpdate()
	updaq.SetTableName("total_layout")
	b, _ := json.Marshal(req.ContainerOrder)
	order := string(b)
	if order != "" {
		updaq.SetUpdateValue("container_order=?", order)
	}
	if req.AndroidStartVersion != 0 {
		updaq.SetUpdateValue("android_start_version=?", req.AndroidStartVersion)
	}
	if req.AndroidEndVersion != 0 {
		updaq.SetUpdateValue("android_end_version=?", req.AndroidEndVersion)
	}
	if req.IosStartVersion != 0 {
		updaq.SetUpdateValue("ios_start_version=?", req.IosStartVersion)
	}
	if req.IosEndVersion != 0 {
		updaq.SetUpdateValue("ios_end_version=?", req.IosEndVersion)
	}
	updaq.SetUpdateValue("source=?", req.Source)
	updaq.SetUpdateValue("update_tick=?", time.Now().Unix())
	updaq.PushCondition("id=?", req.Id)
	sql, values := updaq.GenerateSQL()
	mysqlHelper := db.GetHomePageInfoMysqlHelper()
	_, err2 := mysqlHelper.Exec(sql, values...)
	if err2 != nil {
		log.Errorf("update total_layout fail ,~~~TotalLayoutUpdate,err is %s", err2.Error())
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	}
	return errorcode.EC_GL_SUCCESS, errorcode.Msg(errorcode.EC_GL_SUCCESS)
}

//查询总体容器布局控制
func (p *AdminManageService) TotalLayoutList(source int) (uint, string, []*TotalLayoutListReq) {
	data := make([]*TotalLayoutListReq, 0)
	daq := datatable.NewDataTableQuery()
	daq.SetTableName("total_layout")
	daq.PushField(&datatable.FiledItem{Alias: "id", Field: "id"})
	daq.PushField(&datatable.FiledItem{Alias: "source", Field: "source"})
	daq.PushField(&datatable.FiledItem{Alias: "container_order", Field: "container_order"})
	daq.PushField(&datatable.FiledItem{Alias: "android_start_version", Field: "android_start_version"})
	daq.PushField(&datatable.FiledItem{Alias: "android_end_version", Field: "android_end_version"})
	daq.PushField(&datatable.FiledItem{Alias: "ios_start_version", Field: "ios_start_version"})
	daq.PushField(&datatable.FiledItem{Alias: "ios_end_version", Field: "ios_end_version"})
	daq.PushField(&datatable.FiledItem{Alias: "update_tick", Field: "update_tick"})
	daq.PushField(&datatable.FiledItem{Alias: "insert_tick", Field: "insert_tick"})
	daq.PushCondition("source = ?", source)
	sql, values := daq.GenerateSQL()
	mysqlHelper := db.GetHomePageInfoMysqlHelper()
	results, err := mysqlHelper.Query(sql, values...)
	if err != nil {
		log.Errorf("query total_layout fail ,~~~TotalLayoutList,err is %s", err.Error())
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR), data
	}
	for _, dt := range results {
		item := &TotalLayoutListReq{}
		item.Id = mysqlHelper.GetColInt(dt, "id")

		containOrder := make([]int, 0)
		order := dt["container_order"].([]byte)
		json.Unmarshal(order, &containOrder)
		item.ContainerOrder = containOrder

		item.Source = mysqlHelper.GetColInt(dt, "source")
		item.AndroidStartVersion = mysqlHelper.GetColInt(dt, "android_start_version")
		item.AndroidEndVersion = mysqlHelper.GetColInt(dt, "android_end_version")
		item.IosStartVersion = mysqlHelper.GetColInt(dt, "ios_start_version")
		item.IosEndVersion = mysqlHelper.GetColInt(dt, "ios_end_version")
		item.InsertTime = time.Unix(mysqlHelper.GetColInt64(dt, "insert_tick"), 0).Format("2006-01-02 15:04:05")
		item.UpdateTime = time.Unix(mysqlHelper.GetColInt64(dt, "update_tick"), 0).Format("2006-01-02 15:04:05")

		data = append(data, item)
	}
	return errorcode.EC_GL_SUCCESS, errorcode.Msg(errorcode.EC_GL_SUCCESS), data
}

//添加容器
func (p *AdminManageService) ContainerAdd(req *ContainerAddReq) (uint, string) {
	//插入
	nowTick := time.Now().Unix()
	data := make(map[string]*utility.MySQLFieldValue)
	data["source"] = utility.NewMySQLFieldValue(req.Source, false)
	data["container_type"] = utility.NewMySQLFieldValue(req.ContainerType, false)
	data["container_name"] = utility.NewMySQLFieldValue(req.ContainerName, false)
	data["more_routers"] = utility.NewMySQLFieldValue(req.MoreRouters, false)

	layout, _ := json.Marshal(req.Layout)
	data["layout"] = utility.NewMySQLFieldValue(string(layout), false)

	itemOrder, _ := json.Marshal(req.ItemOrder)
	data["item_order"] = utility.NewMySQLFieldValue(string(itemOrder), false)

	data["insert_tick"] = utility.NewMySQLFieldValue(nowTick, false)
	data["update_tick"] = utility.NewMySQLFieldValue(nowTick, false)
	mysqlHelper := db.GetHomePageInfoMysqlHelper()
	_, err := mysqlHelper.SaveRecord(data, "container")
	if err != nil {
		log.Errorf("insert container fail ,~~~ContainerAdd,err is %s", err.Error())
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	}
	return errorcode.EC_GL_SUCCESS, errorcode.Msg(errorcode.EC_GL_SUCCESS)
}

//修改容器
func (p *AdminManageService) ContainerUpdate(req *ContainerUpdateReq) (uint, string) {
	updaq := datatable.NewDataTableUpdate()
	updaq.SetTableName("container")

	if req.ContainerType != 0 {
		updaq.SetUpdateValue("container_type=?", req.ContainerType)
	}
	if req.ContainerName != "" {
		if req.ContainerName == "null" {
			req.ContainerName = ""
		}
		updaq.SetUpdateValue("container_name=?", req.ContainerName)
	}
	if req.MoreRouters != "" {
		if req.MoreRouters == "null" {
			req.MoreRouters = ""
		}
		updaq.SetUpdateValue("more_routers=?", req.MoreRouters)
	}

	layout, _ := json.Marshal(req.Layout)
	if string(layout) != "" {
		updaq.SetUpdateValue("layout=?", string(layout))
	}

	itemOrder, _ := json.Marshal(req.ItemOrder)
	if string(itemOrder) != "" {
		updaq.SetUpdateValue("item_order=?", string(itemOrder))
	}
	updaq.SetUpdateValue("source=?", req.Source)
	updaq.SetUpdateValue("update_tick=?", time.Now().Unix())
	updaq.PushCondition("container_id=?", req.ContainerId)
	sql, values := updaq.GenerateSQL()
	mysqlHelper := db.GetHomePageInfoMysqlHelper()
	_, err2 := mysqlHelper.Exec(sql, values...)
	if err2 != nil {
		log.Errorf("update total_layout fail ,~~~ContainerUpdate,err is %s", err2.Error())
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR)
	}
	return errorcode.EC_GL_SUCCESS, errorcode.Msg(errorcode.EC_GL_SUCCESS)
}

//查询容器列表
func (p *AdminManageService) ContainerList(source, containerType int) (uint, string, []*ContainerListReq) {
	data := make([]*ContainerListReq, 0)
	daq := datatable.NewDataTableQuery()
	daq.SetTableName("container")
	daq.PushField(&datatable.FiledItem{Alias: "container_id", Field: "container_id"})
	daq.PushField(&datatable.FiledItem{Alias: "source", Field: "source"})
	daq.PushField(&datatable.FiledItem{Alias: "container_type", Field: "container_type"})
	daq.PushField(&datatable.FiledItem{Alias: "container_name", Field: "container_name"})
	daq.PushField(&datatable.FiledItem{Alias: "more_routers", Field: "more_routers"})
	daq.PushField(&datatable.FiledItem{Alias: "layout", Field: "layout"})
	daq.PushField(&datatable.FiledItem{Alias: "item_order", Field: "item_order"})
	daq.PushField(&datatable.FiledItem{Alias: "update_tick", Field: "update_tick"})
	daq.PushField(&datatable.FiledItem{Alias: "insert_tick", Field: "insert_tick"})
	daq.PushCondition("source = ?", source)
	if containerType != 0 {
		daq.PushCondition("container_type = ?", containerType)
	}
	sql, values := daq.GenerateSQL()
	mysqlHelper := db.GetHomePageInfoMysqlHelper()
	results, err := mysqlHelper.Query(sql, values...)
	if err != nil {
		log.Errorf("query container fail ,~~~ContainerList,err is %s", err.Error())
		return errorcode.EC_GL_INTERNAL_ERROR, errorcode.Msg(errorcode.EC_GL_INTERNAL_ERROR), data
	}
	for _, dt := range results {
		item := &ContainerListReq{}
		item.ContainerId = mysqlHelper.GetColInt(dt, "container_id")

		layout := make(map[string]interface{})
		ly := dt["layout"].([]byte)
		json.Unmarshal(ly, &layout)
		item.Layout = layout

		itemOrder := make([]int, 0)
		io := dt["item_order"].([]byte)
		json.Unmarshal(io, &itemOrder)
		item.ItemOrder = itemOrder

		item.Source = mysqlHelper.GetColInt(dt, "source")
		item.ContainerType = mysqlHelper.GetColInt(dt, "container_type")
		item.ContainerName = mysqlHelper.GetColString(dt, "container_name")
		item.MoreRouters = mysqlHelper.GetColString(dt, "more_routers")
		item.InsertTime = time.Unix(mysqlHelper.GetColInt64(dt, "insert_tick"), 0).Format("2006-01-02 15:04:05")
		item.UpdateTime = time.Unix(mysqlHelper.GetColInt64(dt, "update_tick"), 0).Format("2006-01-02 15:04:05")

		data = append(data, item)
	}
	return errorcode.EC_GL_SUCCESS, errorcode.Msg(errorcode.EC_GL_SUCCESS), data
}
